﻿using Orleans;
using Orleans.Runtime;
using Sample.Interfaces;
using System;
using System.Threading.Tasks;

namespace Sample.Implements
{
    public sealed class NewsReminderGrain : Grain, INewsReminderGrain
    {
        internal IGrainRuntime Runtime { get; set; }

        public async Task RemoveReminder(string reminder)
        {
            var reminderType = await GetReminder(reminder);

            await UnregisterReminder(reminderType);
        }

        public async Task<IGrainReminder> StartReminder(string reminderName, TimeSpan? p = null)
        {
            var usePeriod = p.Value;

            var reminder = await RegisterOrUpdateReminder(reminderName, usePeriod - TimeSpan.FromSeconds(2), usePeriod);

            return reminder;
        }
        
        public Task ReceiveReminder(string reminderName, TickStatus status)
        {
            Console.WriteLine("Thanks for reminding me-- I almost forgot!");

            return Task.CompletedTask;
        }

        public Task RegisterTimerTask()
        {

            //几个注意事项
            //1. Timer定时调用不会改变当前grain实例的状态(grain实例状态: 空闲 idle、使用中use),如果你通过Timer来延迟grian因为空闲太久而被回收(从idle到use状态装换)，是行不通的。也就是说即使有timer,如果这个grain一直没有被调用过，这个grain可能会因为空闲太久而被转为非激活状态，timer就不在继续运行
            //2. Timer的周期，指的是从上一次的调用成功后，到下次调用开始前的一段时间，Orleans的Timer不仅不会发生类似于System.Theading.Timer的重叠调用，而且延长调用周期为【固定的周期 + 上一次调用的时间】
            //3. Timer的调用，不会和这个grain上的其它调用并行执行。而且asyncCallback不会想其它调用一样做为消息传递

            // 生命周期
            // 如果不手动释放，该计时器寄生与当前 Grain 实例

            var timerloop = this.RegisterTimer(obj =>
            {
                // 使用传入参数obj执行任务
                return Task.CompletedTask;
            },
            new object(),                  // 传入参数
            TimeSpan.FromSeconds(60),      // 指定定时器开始执行时第一次执行的等待时间（延迟多久开始执行） 
            TimeSpan.FromSeconds(1)        // 指定定时器执行的时间间隔
            );

            // 释放定时器
            // timerloop.Dispose();

            return Task.CompletedTask;

        }
    }
}